package com.github.fujianlian.klinechart.draw.main;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.github.fujianlian.klinechart.BaseKLineChartView;
import com.github.fujianlian.klinechart.KLineChartView;
import com.github.fujianlian.klinechart.R;
import com.github.fujianlian.klinechart.base.IValueFormatter;
import com.github.fujianlian.klinechart.draw.BaseDraw;
import com.github.fujianlian.klinechart.draw.Status;
import com.github.fujianlian.klinechart.entity.h.ICandle;
import com.github.fujianlian.klinechart.formatter.ValueFormatter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 主图的实现类
 * Created by tifezh on 2016/6/14.
 */
public abstract class BaseMainDraw<T> extends BaseDraw<T, ICandle> {

    protected int color_008080;
    protected float mCandleWidth = 0;
    protected float mCandleLineWidth = 0;
    protected Paint mMainLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    protected Paint mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    protected Paint mRedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    protected Paint mGreenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    protected Paint mSelectorTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    protected Paint mSelectorBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    protected boolean mCandleSolid = false;
    // 是否分时
    protected boolean isLine = false;
    protected Status.Sta status = Status.ENE;
    protected KLineChartView kChartView;
    protected int chart_red;
    protected int chart_green;
    protected int color_6495ED;
    protected int color_8B008B;
    protected int color_CD2990;
    protected int color_faa755;
    protected int color_2e3a1f;
    protected int color_b2d235;
    protected int color_444693;
    protected List<BaseMainDraw> mainDrawList = new ArrayList<>();
    // 指标ID
    protected int mDrawId;
    // 指标图层
    protected int mZorder = 0;


    public int getmZorder() {
        return mZorder;
    }

    public void setmZorder(int mZorder) {
        this.mZorder = mZorder;
    }

    public void addMainDraw(BaseMainDraw draw) {
        if (draw == null || mainDrawList.contains(draw))
            return;
        mainDrawList.add(draw);
        Collections.sort(mainDrawList, (baseMainDraw, t1) -> baseMainDraw.getmZorder() -t1.getmZorder());
    }

    public void removeMainDraw(BaseMainDraw draw) {
        if (draw == null || !mainDrawList.contains(draw))
            return;
        mainDrawList.remove(draw);

        Collections.sort(mainDrawList, (baseMainDraw, t1) -> baseMainDraw.getmZorder() -t1.getmZorder());

    }

    public BaseMainDraw(int id) {
        super(null);
        this.mDrawId = id;
    }

    public BaseMainDraw(BaseKLineChartView view, int id) {
        this(id);
        init(view);
    }

 public BaseMainDraw(BaseKLineChartView view) {
        this(-1);
        init(view);
    }


    @Override
    public void init(BaseKLineChartView view) {
        Context context = view.getContext();
        kChartView = (KLineChartView) view;

        chart_red = ContextCompat.getColor(context, R.color.chart_red);
        chart_green = ContextCompat.getColor(context, R.color.chart_green);
        color_6495ED = ContextCompat.getColor(context, R.color.color_6495ED);
        color_008080 = ContextCompat.getColor(context, R.color.color_008080);
        color_8B008B = ContextCompat.getColor(context, R.color.color_8B008B);
        color_CD2990 = ContextCompat.getColor(context, R.color.color_CD2990);
        color_faa755 = ContextCompat.getColor(context, R.color.color_faa755);
        color_2e3a1f = ContextCompat.getColor(context, R.color.color_2e3a1f);
        color_b2d235 = ContextCompat.getColor(context, R.color.color_b2d235);
        color_444693 = ContextCompat.getColor(context, R.color.color_444693);


        mRedPaint.setAlpha(50);
        mMainLinePaint.setStyle(Paint.Style.STROKE);
        setLineWidth(5);

    }

    protected boolean changeColor = false;

    public void changgeColor(boolean changeColor) {
        this.changeColor = changeColor;
        if (changeColor) {
            mRedPaint.setColor(Color.BLACK);
            mGreenPaint.setColor(Color.GRAY);
            mLinePaint.setColor(Color.GRAY);
            mLinePaint.setStrokeWidth(2);
            mMainLinePaint.setColor(Color.GRAY);
        } else {
            mRedPaint.setColor(chart_red);
            mGreenPaint.setColor(chart_green);
            mLinePaint.setColor(ContextCompat.getColor(kChartView.getContext(), R.color.chart_line));
            mLinePaint.setStrokeWidth(2);
            mMainLinePaint.setColor(ContextCompat.getColor(kChartView.getContext(), R.color.chart_line_background));
        }

    }

    /**
     * 判断当前的绘制器是否显示 ，
     * @param status  参数兼容原有版本， 参数已改为设置时会设置进来 不用传参了
     * @return
     */
    public boolean isStatus(Status.Sta status) {
        try {
            if (this.status.getId() == mDrawId || mDrawId<0) {
                return true;
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    public Status.Sta getStatus() {
        return status;
    }

    protected boolean isPriceTheSame(ICandle curPoint) {
        return curPoint.getHigh() == curPoint.getLow() && curPoint.getOpen() == curPoint.getClose();
    }


    @Override
    public Float getMaxValue(ICandle point) {
        if (Status.ENE.equals(status) || Status.MA_ENE.equals(status)) {
            if (point.getENE_UPPER() == 0) {
                return Math.max(point.getHigh(), (float) point.getStopWin());
            } else {
                return Math.max(Math.max(point.getENE_UPPER(), point.getHigh()), (float) point.getStopWin());
            }
        } else if (Status.BOLL.equals(status) || Status.MA_BOLL.equals(status)) {
            if (Float.isNaN(point.getUp())) {
                if (point.getMb() == 0) {
                    return Math.max(point.getHigh(), (float) point.getStopWin());
                } else {
                    return Math.max(point.getMb(), (float) point.getStopWin());
                }
            } else if (point.getUp() == 0) {
                return Math.max(point.getHigh(), (float) point.getStopWin());
            } else {
                return point.getUp();
            }
        } else if (Status.ENE_BOLL.equals(status)) {
            return maxValue(point.getENE_UPPER() == 0 ? point.getHigh() : point.getENE_UPPER(), point.getHigh(), maxValue((float) point.getStopWin(), point.getMb() == 0 ? (float) point.getStopWin() : point.getMb()));
        }
        return Math.max(Math.max(point.getHigh(), point.getMa().getMA30Price()), (float) point.getStopWin());

    }

    @Override
    public float getMinValue(ICandle point) {


        if (Status.ENE.equals(status) || Status.MA_ENE.equals(status)) {
            return minValue(point.getENE_LOWER() == 0 ? point.getLow() : point.getENE_LOWER(), point.getLow(), (float) point.getStopWin());
        } else if (Status.BOLL.equals(status) || Status.MA_BOLL.equals(status)) {
            return minValue(point.getDn() == 0 ? (float) point.getStopWin() : point.getDn(), (float) point.getStopWin());
        } else if (Status.ENE_BOLL.equals(status)) {
            return minValue(point.getDn() == 0 ? (float) point.getStopWin() : point.getDn(), (float) point.getStopWin(), minValue(point.getENE_LOWER() == 0 ? point.getLow() : point.getENE_LOWER(), point.getLow()));
        }

        float value = minValue(point.getMa().getMA5Price(), point.getMa().getMA10Price(), minValue(point.getMa().getMA20Price(), point.getMa().getMA30Price(), point.getMa().getMA60Price()));


        return minValue(value == 0 ? point.getLow() : value, point.getLow(), (float) point.getStopWin());


    }

    private float minValue(float v1, float v2) {
        return v1 <= 0 ? (v2 <= 0 ? 0 : v2) : (v2 <= 0 ? v1 : Math.min(v1, v2));
    }

    private float minValue(float v1, float v2, float v3) {
        if (v1 <= 0) {
            return minValue(v2, v3);
        } else if (v2 <= 0) {
            return minValue(v1, v3);
        } else if (v3 <= 0) {
            return minValue(v1, v2);
        } else {
            return Math.min(Math.min(v1, v2), v3);
        }
    }

    private float maxValue(float v1, float v2) {
        return Math.max(v1, v2);
    }

    private float maxValue(float v1, float v2, float v3) {
        if (v1 <= 0) {
            return maxValue(v2, v3);
        } else if (v2 <= 0) {
            return maxValue(v1, v3);
        } else if (v3 <= 0) {
            return maxValue(v1, v2);
        } else {
            return Math.max(Math.max(v1, v2), v3);
        }
    }

    @Override
    public IValueFormatter getValueFormatter() {
        return new ValueFormatter();
    }


    @Override
    public void drawTranslated(@Nullable ICandle lastPoint, @NonNull ICandle curPoint, float lastX, float curX, @NonNull Canvas canvas, @NonNull BaseKLineChartView view, int position) {

    }

    @Override
    public void drawTranslateds(Canvas canvas, BaseKLineChartView view, List<ICandle> datas, int mStartIndex, int mStopIndex) {

    }

    protected void drawMain(@Nullable ICandle lastPoint, @NonNull ICandle curPoint, float lastX, float curX, @NonNull Canvas canvas, @NonNull BaseKLineChartView view) {
        if (isLine) {
            view.drawMainLine(canvas, mLinePaint, lastX, lastPoint.getClose(), curX, curPoint.getClose());
        } else {
            drawCandle(view, canvas, curX, curPoint, lastPoint);
        }

    }


    /**
     * 画Candle
     *
     * @param canvas
     * @param x      x轴坐标
     */
    protected void drawCandle(BaseKLineChartView view, Canvas canvas, float x, ICandle curPoint, ICandle lapoint) {
        boolean thesame = isPriceTheSame(curPoint);
        float v = thesame ? curPoint.getClose() / 3000 : 0;
        float high = curPoint.getHigh() + v, low = curPoint.getLow() - v, theopen = curPoint.getOpen() + v, theclose = curPoint.getClose() - v;

        high = view.getMainY(high);
        low = view.getMainY(low);
        float open = view.getMainY(theopen);
        float close = view.getMainY(theclose);
        float r = mCandleWidth / 2;
        float lineR = mCandleLineWidth / 2;
        Paint paint;

        if (theclose > theopen || (thesame && curPoint.getClose() > lapoint.getClose())) {
            paint = mRedPaint;
            //实心
            if (mCandleSolid) {
                canvas.drawRect(x - r, close, x + r, open, paint);
                canvas.drawRect(x - lineR, high, x + lineR, low, paint);
            } else {

                //上下影线
                paint.setStrokeWidth(mCandleLineWidth);
                canvas.drawLine(x, high, x, close, paint);
                canvas.drawLine(x, open, x, low, paint);
                //两侧竖线
                canvas.drawLine(x - r + lineR, open, x - r + lineR, close, paint);
                canvas.drawLine(x + r - lineR, open, x + r - lineR, close, paint);

                // 上下横线

                paint.setStrokeWidth(mCandleLineWidth * view.getScaleX());
                canvas.drawLine(x - r, open, x + r, open, paint);
                canvas.drawLine(x - r, close, x + r, close, paint);
            }

        } else if (theopen > theclose) {
            paint = mGreenPaint;
            if (mCandleSolid) {
                canvas.drawRect(x - r, open, x + r, close, paint);
                canvas.drawRect(x - lineR, high, x + lineR, low, paint);
            } else {
                paint.setStrokeWidth(mCandleLineWidth);
                canvas.drawLine(x, high, x, open, paint);
                canvas.drawLine(x, close, x, low, paint);

                //两侧竖线
                canvas.drawLine(x - r + lineR, open, x - r + lineR, close, paint);
                canvas.drawLine(x + r - lineR, open, x + r - lineR, close, paint);

                // 上下横线

                paint.setStrokeWidth(mCandleLineWidth * view.getScaleX());
                canvas.drawLine(x - r, open, x + r, open, paint);
                canvas.drawLine(x - r, close, x + r, close, paint);
//                canvas.drawRect(x - r, open, x + r, close, mGreenPaint);
//                canvas.drawRect(x - lineR, high, x + lineR, low, mGreenPaint);

            }
        } else {
            canvas.drawRect(x - r, open, x + r, close + 1, mRedPaint);
            canvas.drawRect(x - lineR, high, x + lineR, low, mRedPaint);

        }
    }


    /**
     * 设置蜡烛宽度
     *
     * @param candleWidth
     */
    public void setCandleWidth(float candleWidth) {
        mCandleWidth = candleWidth;
    }

    /**
     * 设置蜡烛线宽度
     *
     * @param candleLineWidth
     */
    public void setCandleLineWidth(float candleLineWidth) {
        mCandleLineWidth = candleLineWidth;
    }


    /**
     * 设置曲线宽度
     */
    public void setLineWidth(float width) {

        mLinePaint.setStrokeWidth(width);
    }


    /**
     * 蜡烛是否实心
     */
    public void setCandleSolid(boolean candleSolid) {
        mCandleSolid = candleSolid;
    }

    public void setLine(boolean line) {
        if (isLine != line) {
            isLine = line;
            if (isLine) {
                kChartView.setCandleWidth(kChartView.dp2px(7f));
            } else {
                kChartView.setCandleWidth(kChartView.dp2px(6f));
            }

        }
    }

    public boolean isLine() {
        return isLine;
    }


    public void setSelectorTextColor(int color) {

    }

    public void setSelectorTextSize(float textSize) {

    }

    public void setSelectorBackgroundColor(int color) {

    }

    public void setTextSize(float textSize) {

    }

    public void setStatus(Status.Sta status) {
        this.status = status;
    }

    public void setMa30Color(int color) {

    }

    public void setMa10Color(int color) {

    }

    public void setMa5Color(int color) {
    }

    public void setStrokeWidth(float width) {
    }
}
